package cn.abcsys.cloud.devops.runtime.service.impl;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;

import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;

import cn.abcsys.cloud.devops.runtime.common.NginxConfig;
import cn.abcsys.cloud.devops.runtime.core.LoadBalanceCore;
import cn.abcsys.cloud.devops.runtime.model.HostModel;
import cn.abcsys.cloud.devops.runtime.model.LoadBalanceTemplate;
import cn.abcsys.cloud.devops.runtime.service.LoadBalanceService;

/**
 * 
 * mayunhao
 */
@Component
public class LoadBalanceServiceImpl implements LoadBalanceService {
	private static final Logger LOGGER = Logger.getLogger(LoadBalanceServiceImpl.class);
	@Autowired
	private NginxConfig nginxConfig;
	@Autowired
	private LoadBalanceCore loadBalanceCore;
	
	private LoadBalanceTemplate getlbTemplate(){
		//1、将对象转为Jsonarray
		/**
		 * [{applicationName:tomcat_v1,servicePorts:[{port:8080,url:/hello,
		 * serviceUrls:[{serviceUrl:192.168.1.1:8080},{serviceUrl:192.168.1.2:8080}]},
		 * {port:8081,url:/test,serviceUrls:[{serviceUrl:192.168.1.1:8081},{serviceUrl:192.168.1.2:8081}]}]}]
		 */
//		String init = "[{applicationName:tomcat_v1,servicePorts:[{port:8080,url:/hello,serviceUrls:[{serviceUrl:192.168.1.1:8080},{serviceUrl:192.168.1.2:8080}]},{port:8081,url:/test,serviceUrls:[{serviceUrl:192.168.1.1:8081},{serviceUrl:192.168.1.2:8081}]}]}]";
		JSONArray jsonArray = this.getTest();
		if(null==jsonArray){
			LOGGER.error("输入参数为空");
			return null;
		}
		LoadBalanceTemplate maintemplate = new LoadBalanceTemplate();
		//2、分解jsonarray,将相同端口的服务对象重新编排，同时拼接upstream
		StringBuffer upStream = new StringBuffer();
		Map<String,JSONArray> appPortMap = new HashMap<>(); 
		for(int i=0;i<jsonArray.size();i++){
			JSONObject app = jsonArray.getJSONObject(i);
			String applicationName = app.getString("applicationName");
			//端口格式[{port:8080,url:/hello},{port:8081,url:/test}]
			JSONArray servicePortArray = app.getJSONArray("servicePorts");
			for(int j=0;j<servicePortArray.size();j++){
				JSONObject portObject = servicePortArray.getJSONObject(j);
				String port = portObject.getString("port");
				String url_path = portObject.getString("url");
				JSONArray serviceUrls = portObject.getJSONArray("serviceUrls");
				upStream.append(" upstream ");
				System.out.println(upStream);
				upStream.append(applicationName+"-"+port);
				upStream.append("{\n");
//				if(app.getAppHashStatus() == 1){
//					common_upstream += "ip_hash;\n";
//				}
				for(int k=0;k<serviceUrls.size();k++){
					String serviceUrl = serviceUrls.getJSONObject(k).getString("serviceUrl");
					upStream.append(serviceUrl);
					upStream.append(" fail_timeout=1M;\n");
				}
				upStream.append(" server 127.0.0.1:8080 down;\n");
				upStream.append(" }\n");
				//将不同的端口，放在不同的集合中
				if(appPortMap.containsKey(port)){
					JSONArray service_port_set = appPortMap.get(port);
					JSONObject service_port = new JSONObject();
					service_port.put("url_path", url_path);
					service_port.put("proxy_url", applicationName+"-"+port);
					service_port_set.add(service_port);
					appPortMap.put(port, service_port_set);
				}else{
					JSONArray service_port_set = new JSONArray();
					JSONObject service_port = new JSONObject();
					service_port.put("url_path", url_path);
					service_port.put("proxy_url", applicationName+"-"+port);
					service_port_set.add(service_port);
					appPortMap.put(port, service_port_set);
				}
			}
		}
		//3、按照不同端口拼接service
		StringBuffer serverList = new StringBuffer();
		Iterator<Entry<String, JSONArray>> iterator = appPortMap.entrySet().iterator();
		while(iterator.hasNext()){
			Entry<String, JSONArray> entry = iterator.next();
			//端口
			String port = entry.getKey();
			//端口下的服务
			JSONArray port_application = entry.getValue();
			
			StringBuffer server = new StringBuffer("\n");
			server.append("server  {\n");
			server.append("	listen	" + port + ";\n");
			server.append("	server_name  localhost;\n");
			server.append("	proxy_connect_timeout 600s;\n");
			server.append("	proxy_read_timeout 600s;\n");
			server.append("	proxy_send_timeout 600s;\n\n");
			for(int i=0;i<port_application.size();i++){
				JSONObject service_port = port_application.getJSONObject(i);
				String url_path = service_port.getString("url_path");
				String proxy_url = service_port.getString("proxy_url");
				StringBuffer locationTemp = new StringBuffer("location ^~");
				boolean webRoot = false;
				if (url_path.startsWith("/")) {
					url_path = url_path.substring(1);
				}
				if (url_path.endsWith("/")) {
					webRoot = true;
					url_path = url_path.substring(0, url_path.length() - 1);
				}
				if ("".equals(url_path)) {
					locationTemp.append("/");
				} else {
					locationTemp.append("/" + url_path + "/");
				}
				locationTemp.append("{\n");
				locationTemp.append("proxy_set_header X-Real-IP $remote_addr;\n");
				locationTemp.append("proxy_next_upstream off;\n");
				locationTemp.append("proxy_http_version 1.1;\n");
				locationTemp.append("proxy_pass http://");
				locationTemp.append(proxy_url);
				if (webRoot) {
					locationTemp.append("/;");
				} else {
					locationTemp.append(";");
				}
				locationTemp.append("\n}\n");
				server.append(locationTemp);
			}
			server.append(" location /Nginxstatus{\n");
			server.append("	stub_status on;\n");
			server.append("	access_log off;\n");
			server.append("	allow 127.0.0.1;\n");
			server.append(" }\n");
			server.append(" error_page   500 502 503 504  /50x.html;\n");
			server.append(" location = /50x.html {\n");
			server.append("	root   html;\n");
			server.append(" }\n");
			server.append(" }\n");
			serverList.append(server);
		}
		if(StringUtils.isEmpty(serverList.toString())){
			serverList.append("		server{\n");
			serverList.append("			listen 80;\n");
			serverList.append("			server_name  localhost;\n");
			serverList.append("			proxy_connect_timeout 600s;\n");
			serverList.append("			proxy_read_timeout 600s;\n");
			serverList.append("			proxy_send_timeout 600s;\n");
			serverList.append("		location / {root   html;\n");
			serverList.append("            index  index.html index.htm;\n}");
			serverList.append("		location /Nginxstatus{\n");
			serverList.append("			stub_status on;\n");
			serverList.append("			access_log off;\n");
			serverList.append("			allow 127.0.0.1;\n");
			serverList.append("		}\n");
			serverList.append("		error_page   500 502 503 504  /50x.html;\n");
			serverList.append("		location = /50x.html {\n");
			serverList.append("			root   html;\n");
			serverList.append("		}\n");
			serverList.append("}\n");
		}
		maintemplate.setUpStream(upStream.toString());
		maintemplate.setServer(serverList.toString());
		maintemplate.setLocalFile(nginxConfig.getNginxFile());
		maintemplate.setLocalTemplate(nginxConfig.getNginxTemp());
		maintemplate.setHostModel(getHostModel());
		return maintemplate;
	}
	@Override
	public void reloadBalance() {
		LoadBalanceTemplate lbTemplate = getlbTemplate();
		try {
			if (lbTemplate!=null) {
				List<LoadBalanceTemplate> balanceTemplates = new ArrayList<>();
				balanceTemplates.add(lbTemplate);
				loadBalanceCore.reloadBalance(balanceTemplates);
			} else {
				LOGGER.info("Update loadbalance success:no application to update");
			}

		} catch (Exception e) {
			LOGGER.error("Update loadbalance failed!", e);
		}
	}
	private HostModel getHostModel() {
		HostModel model = new HostModel();
		model.setHostIp("42.159.121.67");
		model.setHostUser("root");
		model.setHostPwd("Beyondcent11");
		return model;
	}
	public JSONArray getTest(){
		JSONObject p1 = new JSONObject();
		JSONArray jsonArray = new JSONArray();
		JSONObject t1 = new JSONObject();
		t1.put("serviceUrl", "192.168.1.1:8080");
		jsonArray.add(t1);
		JSONObject t2 = new JSONObject();
		t2.put("serviceUrl", "192.168.1.2:8080");
		jsonArray.add(t2);
		
		p1.put("port", "8080");
		p1.put("url", "/hello1");
		p1.put("serviceUrls", jsonArray);
		
		JSONObject p11 = new JSONObject();
		JSONArray jsonArray1 = new JSONArray();
		JSONObject t11 = new JSONObject();
		t11.put("serviceUrl", "192.168.1.1:8081");
		jsonArray1.add(t11);
		JSONObject t21 = new JSONObject();
		t21.put("serviceUrl", "192.168.1.2:8081");
		jsonArray1.add(t21);
		
		p11.put("port", "8081");
		p11.put("url", "/hello2");
		p11.put("serviceUrls", jsonArray1);
		
		
		
		JSONArray array = new JSONArray();
		JSONArray array1 = new JSONArray();
		array1.add(p1);
		array1.add(p11);
		JSONObject g = new JSONObject();
		g.put("applicationName", "tomcat_v1");
		g.put("servicePorts", array1);
		array.add(g);
		System.out.println(array);
		return array;
	}
}